﻿#if NETSTANDARD2_0 || NETCOREAPP3_0
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
#else
using System.Configuration;
#endif
using PetaPoco;
using System;
using System.Linq;

namespace Longbow.Data
{
    /// <summary>
    /// 数据库连接适配操作类，创建 IDatabase 用于与数据库交互
    /// </summary>
    public static class DbManager
    {
#if NETSTANDARD2_0 || NETCOREAPP3_0
        /// <summary>
        /// 通过 DI 服务自动读取配置文件创建 IDatabase 操作类
        /// </summary>
        /// <param name="name">配置文件中 ConnectionStrings 键值 Key</param>
        /// <param name="keepAlive">是否保持 Connection 一直处于 Open 状态，此参数为 True 时必须显示手动调用 Dispose 方法</param>
        /// <returns></returns>
        public static IDatabase Create(string name = null, bool keepAlive = false) => DatabaseServiceCollectionExtensions.ServiceProvider.GetRequiredService<IDbAdapter>().Create(name, keepAlive);

        /// <summary>
        /// 通过指定IConfiguration配置项创建IDatabase操作类
        /// </summary>
        /// <param name="configuration">指定配置项，包含 ConnectionStrings 小节与 DB 小节</param>
        /// <param name="name">配置文件中 ConnectionStrings 键值 Key</param>
        /// <param name="keepAlive">是否保持 Connection 一直处于 Open 状态，此参数为 True 时必须显示手动调用 Dispose 方法</param>
        /// <returns></returns>
        public static IDatabase Create(IConfiguration configuration, string name = null, bool keepAlive = false) => new DefaultDbAdapter(configuration).Create(name, keepAlive);
#else
        /// <summary>
        /// 通过DI服务自动读取配置文件创建 IDatabase 操作类
        /// </summary>
        /// <param name="name">配置文件中 ConnectionStrings 键值Key</param>
        /// <param name="keepAlive">是否保持 Connection 一直处于 Open 状态，此参数为True时必须显示手动调用 Dispose 方法</param>
        /// <returns></returns>
        public static IDatabase Create(string name = null, bool keepAlive = false)
        {
            var connectionString = string.IsNullOrEmpty(name)
                ? ConfigurationManager.ConnectionStrings[1].ConnectionString
                : ConfigurationManager.ConnectionStrings[name].ConnectionString;
            var providerName = string.IsNullOrEmpty(name)
                ? ConfigurationManager.ConnectionStrings[1].ProviderName
                : ConfigurationManager.ConnectionStrings[name].ProviderName;
            return Create(new DatabaseOption() { ConnectionString = connectionString, KeepAlive = keepAlive, ProviderName = Enum.TryParse(providerName, true, out DatabaseProviderType pn) ? pn : DatabaseProviderType.SqlServer });
        }
#endif

        /// <summary>
        /// 通过指定DatabaseOption配置项创建 IDatabase 操作类
        /// </summary>
        /// <param name="option">指定 DatabaseOption 配置项</param>
        /// <returns></returns>
        public static IDatabase Create(DatabaseOption option) => DefaultDbAdapter.Create(option);

#if NETSTANDARD2_0 || NETCOREAPP3_0
        /// <summary>
        /// 获取数据库连接字符串
        /// </summary>
        /// <param name="name">为空时获取第一个连接字符串</param>
        /// <returns></returns>
        public static string GetConnectionString(string name = null)
        {
            var config = DatabaseServiceCollectionExtensions.ServiceProvider.GetRequiredService<IConfiguration>();
            return DefaultDbAdapter.RetrieveDatabaseOption(config, name).ConnectionString;
        }

        /// <summary>
        /// 获取 MongoDB 连接字符串信息
        /// </summary>
        /// <param name="name">配置文件中连接字符串配置项名称</param>
        /// <returns></returns>
        public static (string ConnectionString, string DatabaseName) GetMongoDB(string name = null)
        {
            var connectString = GetConnectionString(name);
            var segs = connectString.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
            var databaseName = segs.LastOrDefault().Split(new string[] { "?" }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
            return (connectString, databaseName);
        }
#else
        /// <summary>
        /// 获取连接字符串方法
        /// </summary>
        /// <param name="name">连接字符串 name</param>
        /// <returns></returns>
        public static string GetConnectionString(string name = null)
        {
            return string.IsNullOrEmpty(name)
                ? ConfigurationManager.ConnectionStrings[1].ConnectionString
                : ConfigurationManager.ConnectionStrings[name].ConnectionString;
        }
#endif
    }
}
